home *** CD-ROM | disk | FTP | other *** search
/ Programmers Heaven 2 / Programmers Heaven 2.iso / files / graphics / library / wgt51_r2.zip / WGT5 / EXAMPLES / WGT58.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-03  |  12.1 KB  |  481 lines

  1. /*
  2. ==============================================================================
  3.               WordUp Graphics Toolkit Version 5.0
  4.                  Demonstration Program 58
  5.  
  6.  This is a PACMAN clone which uses the scrolling library.  Use the arrow      
  7.  keys to move around and eat the pellets.  Hit ESC to quit.                   
  8.                                           
  9.  The ghosts move randomly, and you have unlimited lives.  As an exercise,     
  10.  complete the game by adding lives, fruit, intelligent ghosts, and levels.    
  11.  
  12.  *** PROJECT ***                                                             
  13.  This program requires the files WGT5_WC.LIB and WSCR_WC.LIB to be linked.   
  14.                                           
  15.  *** DATA FILES ***                                                          
  16.  PACSPR.SPR,  PACTILE.SPR, PACMAN.WMP                                        
  17.                                WATCOM C++ VERSION 
  18. ==============================================================================
  19. */
  20.  
  21. #include <dos.h>
  22. #include <malloc.h>
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <conio.h>
  26. #include <wgt5.h>
  27. #include <wgtscrol.h>
  28.  
  29. #define UP 72
  30. #define DOWN 80
  31. #define LEFT 75
  32. #define RIGHT 77
  33. #define ESC 1
  34. #define WIN 0
  35.  
  36. #define DESIRED_FRAMERATE 40
  37.  
  38. #define NUM_LOAD 100
  39. #define DIESPEED 40
  40.  
  41. short spx, spy;                    /* Speed of scrolling window */
  42. short pacanim, pacdir;             /* Controls animation frame and the direction
  43.                       PACMAN is facing */
  44. short ox, oy;                      /* Stores PACMAN's coordinate from previous
  45.                       frame, in case you hit a wall */
  46. wgtmap pacmap;                     /* our world map */
  47. short dying;                       /* Counts down after dying.  Once it hits 0,
  48.                       PACMAN starts a new life. */
  49. color palette[256];                /* Our palette of colours */
  50. block pactile[NUM_LOAD + 1];       /* Tiles for the map */
  51. block pacspr[NUM_LOAD + 1];        /* Our sprites */
  52. scrollsprite wobject[100];         /* A few objects for you, ghosts, etc */
  53. short tiletypes[256];              /* Tile types */
  54.  
  55. short pacspeed = 4, ghostspeed = 1;/* Moving speed of you and the ghosts */
  56. short oldmode;                     /* Previous video mode */
  57.  
  58. short bonus;                       /* Tells how many points eating a ghost will
  59.                       give you  0 = 100, 1 = 200, 2 = 400,
  60.                       3 = 800 */
  61. short traptime[5];                 /* Time left until ghost reappears */
  62. static short moved[5], movedir[5]; /* Controls movement of ghosts */
  63. short bluetime;                    /* Time left with blue ghosts */
  64. int timer, totaltime;
  65. short i;
  66. short score;                       /* Your score */
  67. short level;                       /* Current level */
  68. short bonusscore[5] = {100, 200, 400, 800}; /* Bonus points for each ghost */
  69. short total_dots;                  /* Dots not eaten */
  70.  
  71. void checkpos(void);               /* checks PACMAN for hitting walls */
  72. void moveghost(short);             /* checks ghosts for hitting walls */
  73.  
  74. short oldmode;
  75.  
  76. short frames = 0;
  77.  
  78.  
  79. void timerctr (void)
  80. {
  81.   timer++;
  82.   totaltime++;
  83. }
  84.  
  85.  
  86. void set_positions (void)
  87. /* Sets the initial positions of the ghosts and pacman */
  88. {
  89.   short i;
  90.  
  91.   wobject[0].on = 1;             /* Set Pacman's position */
  92.   wobject[0].x = 192; 
  93.   wobject[0].y = 176;
  94.   wobject[0].num = 1;
  95.  
  96.   for (i = 1; i < 5; i++)
  97.   {
  98.     wobject[i].on = 1;
  99.     wobject[i].x = 176;  /* Set up the ghosts */
  100.     wobject[i].y = 112; 
  101.     wobject[i].num = 20 + i;  /* Make the ghosts different colors */
  102.   }
  103.  
  104.   for (i = 1; i < 5; i++) 
  105.   {
  106.     moved[i] = 16;
  107.     movedir[i] = 4;
  108.   }
  109.   pacanim = 1;
  110. }
  111.  
  112.  
  113. void count_dots (void)
  114. {
  115.   unsigned short *mapptr;
  116.   int size, i;
  117.  
  118.   mapptr = pacmap;
  119.   total_dots = 0;
  120.  
  121.   for (i = 0; i < mapwidth[WIN] * mapheight[WIN]; i++)
  122.   {
  123.     if ((tiletypes[*mapptr] == 2) || (tiletypes[*mapptr] == 3))
  124.        total_dots++;
  125.     mapptr++;
  126.   }
  127. }
  128.  
  129.  
  130.  
  131. void incscore(short amt)
  132. /* Increases your score by amt and shows the change on the screen. */
  133. {
  134.   score += amt;
  135.   wgtprintf (260, 40, NULL, "%i", score);
  136. }
  137.  
  138.  
  139. void show_dots_left (void)
  140. /* Displays how many dots are left. */
  141. {
  142.   wgtprintf (260, 80, NULL, "%3i", total_dots);
  143.   if (total_dots == 0)
  144.   {
  145.     nosound ();
  146.     wfreemap (pacmap);
  147.     pacmap = wloadmap (WIN, "pacman.wmp", tiletypes, wobject);
  148.     set_positions ();
  149.     wshowwindow (WIN, 5, 5);
  150.     count_dots ();
  151.     ghostspeed *= 2;
  152.     if (ghostspeed > 16)
  153.       ghostspeed = 16;
  154.   }
  155. }
  156.  
  157.  
  158. void checkpos(void)
  159. /* Checks your position, and makes sure you don't go through a wall */
  160. {
  161.   short hit = 0;
  162.   short nx;
  163.  
  164.   i = wgetworldblock (WIN, wobject[0].x, wobject[0].y);
  165.   if (tiletypes[i] == 0)
  166.     hit = 1;
  167.   i = wgetworldblock (WIN, wobject[0].x + 15, wobject[0].y);
  168.   if (tiletypes[i] == 0)
  169.     hit = 1;
  170.   i = wgetworldblock (WIN, wobject[0].x, wobject[0].y + 15);
  171.   if ((tiletypes[i] == 0) || (tiletypes[i] == 4))
  172.     hit = 1;
  173.   i = wgetworldblock (WIN, wobject[0].x + 15, wobject[0].y + 15);
  174.   if (tiletypes[i] == 0)
  175.     hit = 1;
  176.   i = wgetworldblock (WIN, wobject[0].x + 7, wobject[0].y + 7);
  177.   if (tiletypes[i] == 2)
  178.   {
  179.     sound (500);
  180.     wputworldblock (WIN, wobject[0].x + 7, wobject[0].y + 7, 12);
  181.     incscore (10);
  182.     total_dots--;
  183.     show_dots_left ();
  184.   }
  185.   if (tiletypes[i] == 3)
  186.   {
  187.     sound (800);
  188.     wputworldblock (WIN, wobject[0].x + 7, wobject[0].y + 7, 12);
  189.     bluetime += 150;
  190.     total_dots--;
  191.     show_dots_left ();
  192.   }
  193.  
  194.   if (wobject[0].x < 4)
  195.   {
  196.     wobject[0].x = mapwidth[WIN] * 16 - 32;
  197.     wshowwindow(WIN, (worldx[WIN] + 144) / 16, worldy[WIN] / 16);
  198.   }
  199.  
  200.   if (wobject[0].x > mapwidth[WIN] * 16 - 17)
  201.   {
  202.     wobject[0].x = 16;
  203.     wshowwindow (WIN, 0, worldy[WIN] / 16);
  204.   }
  205.  
  206.   if (hit == 1)
  207.   {
  208.     wobject[0].x = ox;
  209.     wobject[0].y = oy;
  210.     moved[0] = 0;
  211.   }
  212. }
  213.  
  214.  
  215. void moveghost (short numb)
  216. /* Checks the ghost's position, and makes sure it doesn't go through a wall */
  217. {
  218.   short gox, goy;          /* Coordinate of ghost */
  219.   short hit = 0;
  220.   short j;
  221.  
  222.   gox = wobject[numb].x;
  223.   goy = wobject[numb].y;
  224.  
  225.   /* Makes sure ghost moves in a new direction if it ran into a wall the first time. */
  226.   while ((wobject[numb].x == gox) && (wobject[numb].y == goy))
  227.   {
  228.     if (moved[numb] == 0)
  229.       movedir[numb] = (rand () % 5) + 1; /* Pick a random direction (1-5)  5 = still */
  230.  
  231.     switch(movedir[numb])
  232.     {
  233.       case 1: wobject[numb].x += ghostspeed; 
  234.           break;
  235.       case 2: wobject[numb].x -= ghostspeed; 
  236.           break;
  237.       case 3: wobject[numb].y += ghostspeed; 
  238.           break;
  239.       case 4: wobject[numb].y -= ghostspeed; 
  240.           break;
  241.       case 5: break;
  242.       default:break;
  243.     }
  244.  
  245.     moved[numb] += ghostspeed;
  246.     if (moved[numb] >= 16)
  247.       moved[numb] = 0;
  248.  
  249.     /* Make sure ghost doesn't move off the screen. */
  250.     if (wobject[numb].x < 0)
  251.       wobject[numb].x = 0;
  252.     else if (wobject[numb].x > (mapwidth[WIN] - 1) * 16)
  253.       wobject[numb].x = (mapwidth[WIN] - 1) * 16;
  254.  
  255.     if (wobject[numb].y < 0)
  256.       wobject[numb].y = 0;
  257.     else if (wobject[numb].y > (mapheight[WIN] - 1) * 16)
  258.       wobject[numb].y=(mapheight[WIN] - 1) * 16;
  259.  
  260.  
  261.     j = wgetworldblock (WIN, wobject[numb].x, wobject[numb].y);
  262.     if (tiletypes[j] == 0)
  263.       hit = 1;
  264.     j = wgetworldblock (WIN, wobject[numb].x + 15, wobject[numb].y);
  265.     if (tiletypes[j] == 0)
  266.       hit = 1;
  267.     j = wgetworldblock(WIN, wobject[numb].x, wobject[numb].y + 15);
  268.     if (tiletypes[j] == 0)
  269.       hit = 1;
  270.     if ((tiletypes[j] == 4) & (movedir[numb] == 3))  /* Can't move down through
  271.                             ghost's door */
  272.       hit = 1;
  273.     j = wgetworldblock(WIN, wobject[numb].x + 14, wobject[numb].y + 15);
  274.     if (tiletypes[j] == 0)
  275.       hit = 1;
  276.  
  277.     if (hit == 1)  /* A solid tile was run into */
  278.     {
  279.       wobject[numb].x = gox; /* Set to the old position */
  280.       wobject[numb].y = goy;
  281.       moved[numb] = 0;
  282.       hit = 0;
  283.     }
  284.   }
  285. }
  286.  
  287.  
  288. void main(void)
  289. {
  290.   int framectr;
  291.  
  292.   oldmode = wgetmode ();
  293.   if (!vgadetected ())
  294.   {
  295.     printf ("VGA is required to run this program...");
  296.     exit (1);
  297.   }
  298.  
  299.   printf ("WGT Example #58\n\n");
  300.   printf ("This is a PACMAN clone which uses the scrolling library.  Use the arrow\n");
  301.   printf ("keys to move around and eat the pellets.  Hit ESC to quit.\n");
  302.   printf ("The ghosts move randomly, and you have unlimited lives.  As an exercise,\n");
  303.   printf ("complete the game by adding lives, fruit, intelligent ghosts, and levels.\n");
  304.   printf ("\nPress any key to begin\n");
  305.   getch ();
  306.   
  307.   vga256 ();
  308.   wtextcolor (1);
  309.   wtexttransparent (TEXTFGBG);
  310.   wtextbackground (254);
  311.  
  312.   /* Load the graphics */
  313.   wloadsprites (palette, "pactile.spr", pactile, 1, NUM_LOAD);
  314.   wloadsprites (palette, "pacspr.spr", pacspr, 1, NUM_LOAD);
  315.   wsetpalette (0, 255, palette);
  316.  
  317.   /* load our pacman map */
  318.  
  319.   winitscroll (WIN, NORMAL, -1, 15, 12, pactile);
  320.   pacmap = wloadmap (WIN, "pacman.wmp", tiletypes, wobject);
  321.  
  322.   wcls (0);
  323.   wbutt (0, 0, 319, 199);
  324.   wgtprintf (250, 30, NULL, "SCORE");
  325.   wgtprintf (245, 70, NULL, "DOTS LEFT");
  326.  
  327.   wshowwindow (WIN, 5, 5);
  328.   count_dots ();
  329.  
  330.   installkbd ();
  331.  
  332.   set_positions ();
  333.   framectr = 0;
  334.   timer = 0;
  335.   winittimer ();
  336.   wstarttimer (timerctr, TICKS(DESIRED_FRAMERATE));
  337.   do {
  338.     while (framectr == 0)
  339.       framectr = timer;
  340.     timer = 0;
  341.     do {
  342.     spx = 0;
  343.     spy = 0;
  344.     ox = wobject[0].x;
  345.     oy = wobject[0].y;
  346.  
  347.     if (dying == 0)
  348.     {
  349.       switch(movedir[0])
  350.       {
  351.     case 1: wobject[0].x += pacspeed; 
  352.         break;
  353.     case 2: wobject[0].x -= pacspeed; 
  354.         break;
  355.     case 3: wobject[0].y += pacspeed; 
  356.         break;
  357.     case 4: wobject[0].y -= pacspeed; 
  358.         break;
  359.       }
  360.  
  361.       if (movedir[0] != 0)
  362.       {
  363.     moved[0] += pacspeed;
  364.     checkpos ();
  365.       }
  366.  
  367.       if (moved[0] >=16)
  368.     moved[0] = 0;
  369.  
  370.       if (moved[0] == 0)
  371.       {
  372.     if (kbdon[RIGHT])
  373.     {
  374.       movedir[0] = 1;
  375.       pacdir = 0;
  376.     }
  377.     else if (kbdon[LEFT])
  378.     {
  379.       movedir[0] = 2;
  380.       pacdir = 2;
  381.     }
  382.     else if (kbdon[UP])
  383.     {
  384.       movedir[0] = 4;
  385.       pacdir = 1;
  386.     }
  387.     else if (kbdon[DOWN])
  388.     {
  389.       movedir[0] = 3;
  390.       pacdir = 3;
  391.     }
  392.       }
  393.  
  394.       pacanim++;
  395.       if (pacanim > 5)
  396.     pacanim = 1;
  397.       wobject[0].num = pacanim + (pacdir * 5);     /* Set the sprite image for
  398.                               pacman */
  399.     }
  400.     else  /* Dying loop */
  401.     {
  402.       wobject[0].num = (DIESPEED - dying + 31);
  403.       if (wobject[0].num > 34) 
  404.     wobject[0].num = 34;
  405.       dying--;
  406.       if (dying == 0)
  407.       {
  408.     wobject[0].x = 192; 
  409.     wobject[0].y = 176;
  410.     wobject[0].num = 1;
  411.       }
  412.     }   
  413.  
  414.     if (bluetime > 0)
  415.       bluetime--;
  416.  
  417.     for (i = 1; i < 5; i++)              /* Ghost loop */
  418.     {
  419.       if (traptime[i] == 0)
  420.       {
  421.     moveghost (i);
  422.     if (bluetime > 0)
  423.       wobject[i].num = 25;
  424.     if ((bluetime == 1) || ((bluetime < 40) && (bluetime % 2 == 1)))
  425.       wobject[i].num = 20 + i;
  426.  
  427.     if ((soverlap (i, wobject, pacspr, 0, wobject, pacspr) == 1) && 
  428.       (traptime[i] == 0))
  429.     {
  430.       if (bluetime > 0)
  431.       {
  432.         wobject[i].num = 27 + bonus;
  433.         incscore(bonusscore[bonus]);
  434.         bonus++;
  435.         traptime[i] = 100;
  436.       }
  437.       else if (dying == 0)          /* The ghost caught you */
  438.         dying = DIESPEED;
  439.     }
  440.       }
  441.       else traptime[i]--;
  442.       if (traptime[i] == 1)
  443.       {
  444.     wobject[i].x = 192;
  445.     wobject[i].y = 144;
  446.     wobject[i].num = 20 + i;
  447.     bonus = 0;
  448.       }
  449.     } 
  450.  
  451.     nosound ();
  452.  
  453.     framectr--;
  454.     } while (framectr > 0);
  455.     
  456.     /* Find out the scrolling speed based on where you are in the window. */
  457.     spx = wobject[0].x -  worldx[WIN] - windowmaxx[WIN] / 2 - 1;
  458.     spy = wobject[0].y -  worldy[WIN] - windowmaxy[WIN] / 2 - 1;
  459.     
  460.     wscrollwindow (WIN, spx, spy);
  461.     wshowobjects (WIN, 0, 7, pacspr, wobject);
  462.     
  463.     wputblock (4, 4, scrollblock[0], NORMAL);
  464.     frames++;
  465.   } while (!kbdon[ESC]);                 // until ESC is pressed
  466.   wstoptimer ();
  467.   wdonetimer ();
  468.  
  469.   uninstallkbd ();
  470.   wendscroll (WIN);
  471.   wfreesprites (pactile, 0, NUM_LOAD);
  472.   wfreesprites (pacspr, 0, NUM_LOAD);
  473.   wfreemap (pacmap);
  474.   wsetmode (oldmode);
  475.  
  476.   printf ("Number of Frames: %i\n", frames);
  477.   printf ("Frame Rate:       %f\n", (float)frames / (float)(totaltime / (float)(DESIRED_FRAMERATE)));
  478.  
  479. }
  480.  
  481.